package com.weight.netty;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import com.weight.common.enums.ResultEnum;
import com.weight.common.util.ChannelUtil;
import com.weight.common.util.CommonUtils;
import com.weight.common.util.DateFormUtils;
import com.weight.common.util.JsonResultUtil;
import com.weight.system.order.PO.OrderInfo;
import com.weight.system.order.service.OrderInfoService;
import com.weight.system.overload.PO.OverloadInfo;
import com.weight.system.overload.service.OverloadInfoService;
import com.weight.system.sensor.PO.SensorInfo;
import com.weight.system.sensor.VO.SensorInfoVO;
import com.weight.system.sensor.service.SensorInfoService;
import com.weight.system.weight.PO.WeightInfo;
import com.weight.system.weight.service.WeightInfoService;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.GlobalEventExecutor;
/**
 * 服务端消息处理助手
 * @author jmk
 *
 */
@Component
public class CustomHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

	@Autowired
	private WeightInfoService weightInfoService;
	@Autowired
	private OrderInfoService orderInfoService;
	@Autowired
	private OverloadInfoService overloadInfoService;
	@Autowired
	private SensorInfoService sensorInfoService;
	
    public  static CustomHandler customHandler ;
    @PostConstruct //通过@PostConstruct实现初始化bean之前进行的操作
    public void init() {
    	customHandler = this;
    	customHandler.weightInfoService = this.weightInfoService;
    	customHandler.orderInfoService = this.orderInfoService;
    	customHandler.overloadInfoService = this.overloadInfoService;
    	customHandler.sensorInfoService = this.sensorInfoService;
        //初使化时将已静态化的accessTokenOcrRepository实例化
    }
    /**
     * 	服务器端收到任何一个客户端的消息都会触发这个方法
     * 	连接的客户端向服务器端发送消息，那么其他客户端都收到此消息，自己收到【自己】+消息
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame textWebSocketFrame) throws Exception {
//    	String msg  = textWebSocketFrame.text();
//    	Channel channel = ChannelUtil.getChannel("") ;
//    	
//    	 if(null != channel){
//    		 
//    		 return;
//    	 } 
    }
 
    //表示服务端与客户端连接建立
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();  //其实相当于一个connection
        System.out.println("当前用户数 1：: "+ChannelUtil.userChannelClients.size());
    }
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();

        //验证一下每次客户端断开连接，连接自动地从channelGroup中删除调。
        System.out.println("当前用户数2 ：: "+ChannelUtil.userChannelClients.size());
//        ChannelUtil.removeChannel("");
        //当客户端和服务端断开连接的时候，下面的那段代码netty会自动调用，所以不需要人为的去调用它
//        ChannelUtil.userChannelClients.remove(channel);        
    }

    //连接处于活动状态
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress() +" 上线了");
        System.out.println(channel.toString());
        ChannelUtil.saveChannel(channel);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress() +" 下线了");
        ChannelUtil.removeChannel(channel);
      
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    } 

    /**
     * 	获取数据
     * @param ctx 上下文
     * @param msg 获取的数据
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){
    	try {
    		Channel channel = ctx.channel(); 
        	System.out.println(channel.remoteAddress());
        	System.out.println("接收指令：");
        	System.out.println(msg.toString());
        	String reciveMessage =  msg.toString();
        	
            //保存 并返回 指令
            String command = ChannelUtil.saveTempMsg(channel, reciveMessage);
            Map<String, String> map  = ChannelUtil.getTempMsg(channel);
         	String message =  map.get(command);
         	saveOrderInso(command, message, reciveMessage);
         	
            System.out.println(command);
            //第一次发送注册码
            if(StringUtils.equals("msgcode", command)) {
//                System.out.println("注册码：");
//                System.out.println(ChannelUtil.userAddressMapTemp);
            	return;
            }
           //称重
            saveWeightInfo(command, message) ;
          //超重
            saveOverloadInfo(channel,command, message) ;
          //称重
            saveWeightInfo(command, message) ;
            ctx.flush();
    	}catch(Exception e){
    		System.out.println(e.getMessage());
    	}
    	
    } 
    /**
     *	 指令
     * @param command
     * @param message
     * @param reciveMessage
     */
    public void saveOrderInso(String command, String message, String reciveMessage) {
//     	System.out.println(message);
         //记录指令信息表
         OrderInfo orderInfo = new OrderInfo();
         orderInfo.setOrderMsg(command);
         orderInfo.setOrderDesc(message);        
         orderInfo.setOrderStatue(1);
         orderInfo.setOrderInfoId(CommonUtils.getUUId());
         orderInfo.setStandbyfield1(reciveMessage);
 		 orderInfo.setCreateBy("000");
 		 orderInfo.setUpdateBy("000");        
         customHandler.orderInfoService.insertOrderInfo(orderInfo);
    }
     
    /**
     * 	称重
     * @param command
     * @param message
     * @param reciveMessage
     */
    public void saveWeightInfo(String command, String message) {
//     	System.out.println(message);
         //记录指令信息表

        //称重指令 记录称重表
        if(!StringUtils.equals(command, "0010")) {
        	return;
        }
//			00 01 21 04 11 12 11 10 00 06 01 02 12 34 56 000000
//			A5 5A 16 00 10 00 01 21 04 11 12 11 10 00 06 01 02 12 34 56 00 00 00
//        	A5 5A 21 00 10 00 01 21 04 11 12 11 10 00 06 11 01 02 12 34 56 00 00 00
//			0x14:后面为20个字节数据
//			00 10 称重记录数据
//			00 01序号
//			21 04 11 年月日
//			12 11 10 时分秒
//			00 06 11车号
//			01 单位号
//			02 货号
//			12 34 56 毛重
//			000000皮重
		WeightInfo weightInfo = new WeightInfo(); 
		  
		weightInfo.setWeightData(command);//称重记录数据
		weightInfo.setWeightSeq(message.substring(0,4));//序号		 
		weightInfo.setWeightTime(DateFormUtils.getStringToDate("20" + message.substring(4,16),"YYYYMMddHHmmss"));//年月日时分秒
		weightInfo.setWeightCar(message.substring(16,22));//车号
		weightInfo.setWeightOrg(message.substring(22,24));//单位号
		weightInfo.setWeightGood(message.substring(24,26));//货号
		weightInfo.setWeightMweight(message.substring(26,32));//毛重
		weightInfo.setWeightPweight(message.substring(32));//皮重   
    	weightInfo.setWeightId(CommonUtils.getUUId());
		weightInfo.setCreateBy("000");
		weightInfo.setUpdateBy("000");
		weightInfo.setWeightStatus(1);
		customHandler.weightInfoService.insertWeightInfo(weightInfo);
    }
        
    /**
    * 	超重
    * @param command
    * @param message
    * @param reciveMessage
    */
    public void saveOverloadInfo(Channel channel, String command, String message) {
 
       if(!StringUtils.equals(command, "0015")) {
		   return;
	   }
//   			A5 5A 06 00 15 00 12 34 56
//        	   00 15：超载标记
//        	   00 12 34 56：超载值
		
		OverloadInfo overloadInfo = new OverloadInfo(); 
		overloadInfo.setOverloadId(CommonUtils.getUUId());
		overloadInfo.setOverloadDate(new Date());
		overloadInfo.setOverloadCount(new BigDecimal(Double.parseDouble(message)));
		overloadInfo.setCreateBy("000");
		overloadInfo.setUpdateBy("000");
		overloadInfo.setStandbyfield1("1");
		
		String address = channel.remoteAddress().toString();
    	if(StringUtils.contains(address, ":")) {
    		address = address.substring(address.lastIndexOf(":")+1);
    	}
		//注册码
		overloadInfo.setStandbyfield2(ChannelUtil.userAddressMapTemp.get(address));
		
		overloadInfoService.insertOverloadInfo(overloadInfo);
   	 }
    
    public void saveSensorInfo(Channel channel, String command, String message){
    	
        if(!StringUtils.equals(command, "0160")) {
   		   return;
   	    }
//        A5 5A 05 01 60 00 01 XX 
//        01 60：传感器错误标记
//    	00 01：为01号传感器有错误，即为01的ASCII码 
//    	XX为错误代码,说明：00通信中断 ，01号传感器有加密，02仪表没有搜索到传感器
        
        String sensorNum = message.substring(0,4).replaceAll("^(0+)", "");
    	String errorMsg = message.substring(4);
    	SensorInfo sensorInfo=new SensorInfo();
		sensorInfo.setSensorInfoId(CommonUtils.getUUId());
		sensorInfo.setCreateBy("000");
		sensorInfo.setUpdateBy("000");
		sensorInfo.setSensorNum(sensorNum);
		sensorInfo.setSensorStatue(1);
		sensorInfo.setSensorDesc(errorMsg);
		sensorInfo.setSensorDate(new Date());
		String address = channel.remoteAddress().toString();
    	if(StringUtils.contains(address, ":")) {
    		address = address.substring(address.lastIndexOf(":")+1);
    	}
		//注册码
    	sensorInfo.setStandbyfield2(ChannelUtil.userAddressMapTemp.get(address));
		
		
		sensorInfoService.insertSensorInfo(sensorInfo);
    }			 
} 